import { constantRoutes } from '@/router'
import { getRoute } from '@/api/menu'
import Layout from '@/layout'

/**
 * Use meta.role to determine if the current user has permission
 * @param roles
 * @param route
 */
function hasPermission(roles, route) {
  if (route.meta && route.meta.roles) {
    return roles.some((role) => route.meta.roles.includes(role))
  } else {
    return true
  }
}

/**
 * Filter asynchronous routing tables by recursion   通过递归过滤异步路由表
 * @param routes asyncRoutes
 * @param roles
 */
export function filterAsyncRoutes(routes, roles) {
  const res = []

  routes.forEach((route) => {
    const tmp = { ...route }
    if (hasPermission(roles, tmp)) {
      if (tmp.children) {
        tmp.children = filterAsyncRoutes(tmp.children, roles)
      }
      res.push(tmp)
    }
  })

  return res
}

const state = {
  routes: [],
  addRoutes: []
}

const mutations = {
  SET_ROUTES: (state, routes) => {
    state.addRoutes = routes
    state.routes = constantRoutes.concat(routes)
  }
}

const actions = {
  generateRoutes({ commit }, roles) {
    // debugger
    return new Promise((resolve) => {
      const dynamicRoutes = []
      getRoute().then((res) => {
        const { data } = res
        data
          .filter((m) => m.parentId === '00000000-0000-0000-0000-000000000000')
          .forEach((root) => {
            const rootRoute = {
              path: root.routePath,
              component: Layout,
              name: root.routeName,
              alwaysShow: true, // will always show the root menu
              children: [],
              meta: {
                roles: root.roles,
                title: root.menuName,
                icon: root.icon,
                affix: root.isAffix
              },
              hidden: root.isHidden
            }
            data.filter((sub) => sub.parentId === root.id).forEach((sub) => {
              var currentSubRoute = {
                path: sub.routePath,
                component: (resolve) => require(['@/views' + sub.componentPath], resolve),
                name: sub.routeName,
                meta: {
                  roles: sub.roles,
                  title: sub.menuName,
                  icon: sub.icon,
                  affix: sub.isAffix
                },
                hidden: sub.isHidden
              }

              if (sub.redirect) {
                currentSubRoute.redirect = sub.redirect
              }

              rootRoute.children.push(currentSubRoute)
            })
            dynamicRoutes.push(rootRoute)
          })
        let accessedRoutes
        // console.log(dynamicRoutes)

        if (roles.includes('admin')) {
          accessedRoutes = dynamicRoutes || []
        } else {
          accessedRoutes = filterAsyncRoutes(dynamicRoutes, roles)
        }
        accessedRoutes.push(
          // 404 page must be placed at the end !!!
          { path: '*', redirect: '/404', hidden: true }
        )
        commit('SET_ROUTES', accessedRoutes)
        resolve(accessedRoutes)
      })
    })
  }
}

export default {
  namespaced: true,
  state,
  mutations,
  actions
}
